package com.wecommodule.bpm.ext.framework.config.support;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.Serializable;
/**
 * Http连接池通用配置
 *
 */
public class HttpConfigProperties implements Serializable {

    private static final long serialVersionUID = -5431345906837933122L;

    /**
     * 目标服务的简短名称
     */
    @NotNull
    protected String toService = "";

    /**
     * 以毫秒为单位的调用超时值
     */
    protected long callTimeoutMS = 0L;

    /**
     * 以毫秒为单位的连接超时值
     */
    protected long connectTimeoutMS = 0L;

    /**
     * 写入请求超时值（毫秒）。
     */
    protected long writeTimeoutMS = 0L;

    /**
     * 读取请求超时值（毫秒）。
     */
    protected long readTimeoutMS = 0L;

    /**
     * 最大空闲连接阈值
     * 连接池将关闭超过此阈值的更多空闲连接。
     */
    protected int maxIdle = 0;

    /**
     * Keep-alive 时间
     * 超过此值的连接将被连接池关闭
     */
    protected long keepAliveSeconds = 0;

    /**
     * 用户名
     * 如果HTTP Basic鉴权需要
     */
    @Nullable
    protected String username = null;

    /**
     * 密码
     * 如果HTTP Basic鉴权需要
     */
    @Nullable
    protected String password = null;

    /**
     * 请求根路径
     */
    @Nullable
    protected String rootUri = null;

    public HttpConfigProperties() {
        //DO NOTHING
    }


    public HttpConfigProperties(@NotNull HttpConfigProperties other) {
        toService = other.toService;
        callTimeoutMS = other.callTimeoutMS;
        connectTimeoutMS = other.connectTimeoutMS;
        writeTimeoutMS = other.writeTimeoutMS;
        readTimeoutMS = other.readTimeoutMS;
        maxIdle = other.maxIdle;
        keepAliveSeconds = other.keepAliveSeconds;
        username = other.username;
        password = other.password;
        rootUri = other.rootUri;
    }

    @SuppressWarnings("DuplicateStringLiteralInspection")
    public void guard() throws IllegalArgumentException {
        if (StringUtils.isEmpty(toService)) {
            String message = "to-service 参数不能为空.";
            throw new IllegalArgumentException(message);
        }
        if (callTimeoutMS < 0) {
            String message = "无效的HTTP连接池 " + toService + " callTimeoutMS value " + callTimeoutMS
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
        if (connectTimeoutMS < 0) {
            String message = "无效的HTTP连接池 " + toService + " connectTimeoutMS value " + connectTimeoutMS
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
        if (writeTimeoutMS < 0) {
            String message = "无效的HTTP连接池 " + toService + " writeTimeoutMS value " + writeTimeoutMS
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
        if (readTimeoutMS < 0) {
            String message = "无效的HTTP连接池 " + toService + " readTimeoutMS value " + readTimeoutMS
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
        if (maxIdle <= 0) {
            String message = "无效的HTTP连接池 " + toService + " maxIdle value " + maxIdle
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
        if (keepAliveSeconds <= 0) {
            String message = "无效的HTTP连接池 " + toService + " keepAliveSeconds value " + keepAliveSeconds
                    + ". 必须是一个整数.";
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * 返回是否配置了HTTP Basic。
     *
     * @return true -- 已配置; false -- 未配置
     */
    public boolean hasPrincipal() {
        return username != null && password != null;
    }

    // getters and setters required by Spring framework.

    @NotNull
    public String getToService() {
        return toService;
    }

    public void setToService(@NotNull String toService) {
        this.toService = toService;
    }

    public long getCallTimeoutMS() {
        return callTimeoutMS;
    }

    public void setCallTimeoutMS(long callTimeoutMS) {
        this.callTimeoutMS = callTimeoutMS;
    }

    public long getReadTimeoutMS() {
        return readTimeoutMS;
    }

    public void setReadTimeoutMS(long readTimeoutMS) {
        this.readTimeoutMS = readTimeoutMS;
    }

    public long getWriteTimeoutMS() {
        return writeTimeoutMS;
    }

    public void setWriteTimeoutMS(long writeTimeoutMS) {
        this.writeTimeoutMS = writeTimeoutMS;
    }

    public long getConnectTimeoutMS() {
        return connectTimeoutMS;
    }

    public void setConnectTimeoutMS(long connectTimeoutMS) {
        this.connectTimeoutMS = connectTimeoutMS;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public long getKeepAliveSeconds() {
        return keepAliveSeconds;
    }

    public void setKeepAliveSeconds(long keepAliveSeconds) {
        this.keepAliveSeconds = keepAliveSeconds;
    }

    @Nullable
    public String getUsername() {
        return username;
    }

    public void setUsername(@Nullable String username) {
        this.username = username;
    }

    @Nullable
    public String getPassword() {
        return password;
    }

    public void setPassword(@Nullable String password) {
        this.password = password;
    }

    @Nullable
    public String getRootUri() {
        return rootUri;
    }

    public void setRootUri(@Nullable String rootUri) {
        this.rootUri = rootUri;
    }

    @Override
    @NotNull
    public String toString() {
        return new ToStringBuilder(this).append("toService", toService)
                .append("callTimeoutMS", callTimeoutMS).append("connectTimeoutMS", connectTimeoutMS)
                .append("writeTimeoutMS", writeTimeoutMS).append("readTimeoutMS", readTimeoutMS)
                .append("maxIdle", maxIdle).append("keepAliveSeconds", keepAliveSeconds)
                .append("rootUri", rootUri).toString();
    }

}
